﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading;
using SqlSystemWatcher.Common;

namespace SqlSystemWatcher.ExecSessionLog
{
    public class ExecSessionLogger
    {
        private const string SourceClassName = "ExecSessionLog";
        private readonly DataSet _ds = new DataSet();

        public void LoggerStarter()
        {
            const string sqlCommand = "SELECT * FROM [dbo].[uvwLogCheckIntervalConfig] WHERE LogType = 'SessionLog'";
            string conStr = ConfigurationManager.ConnectionStrings["ConStr"].ToString();

            var sqlConnection = new SqlConnection(conStr);
            var sqlDa = new SqlDataAdapter
                {
                    SelectCommand =
                        new SqlCommand(sqlCommand)
                            {
                                CommandType = CommandType.Text,
                                Connection = new SqlConnection(sqlConnection.ConnectionString)
                            }
                };

            string programCode = "sqlDa.SelectCommand.Connection.Open();";
            string connectionString = sqlDa.SelectCommand.Connection.ConnectionString;
            string commandText = "";

            try
            {
                sqlDa.SelectCommand.Connection.Open();
            }
            catch (Exception exception)
            {
                CustomException.WriteInfoScreen(CustomException.InfoScreenLevel.Exception, SourceClassName, programCode, connectionString, sqlDa.SelectCommand.Connection.DataSource, commandText, exception, "");
                return;
            }

            programCode = @"sqlDa.Fill(_ds, ""LogCheckInterval"");";
            connectionString = sqlDa.SelectCommand.Connection.ConnectionString;
            commandText = sqlDa.SelectCommand.CommandText;
            try
            {
                sqlDa.Fill(_ds, "LogCheckInterval");
            }
            catch (Exception exception)
            {
                CustomException.WriteInfoScreen(CustomException.InfoScreenLevel.Exception, SourceClassName, programCode, connectionString, sqlDa.SelectCommand.Connection.DataSource, commandText, exception, "");
                return;
            }
            finally
            {
                sqlDa.SelectCommand.Connection.Close();
            }

            var loggersStates = new ArrayList();

            foreach (DataRow instance in _ds.Tables["LogCheckInterval"].Rows)
            {
                DateTime lastCheckTimeStamp = instance["LastCheck"] != DBNull.Value
                                                  ? (DateTime) instance["LastCheck"]
                                                  : DateTime.MinValue;

                if (lastCheckTimeStamp.AddMinutes((int) instance["CheckInterval"]) > DateTime.Now)
                    continue;

                var execSessionLoggerCore = new ExecSessionLoggerCore(instance["InstanceName"].ToString());
                execSessionLoggerCore.DoIt();

                loggersStates.Add(execSessionLoggerCore);
            }

            while (true)
            {
                bool allCompleted = true;

                foreach (
                    bool a in
                        from object t in loggersStates
                        select (((ExecSessionLoggerCore) (t)).IsFinished)
                        into a where !a select a)
                {
                    allCompleted = false;
                }

                if (allCompleted)
                    break;

                Thread.Sleep(1000);
            }
        }
    }
}